package com.yh.lq.robot;

import com.alibaba.fastjson.JSONObject;
import com.yh.lq.event.LQEvent;
import com.yh.lq.event.message.LQDiscussMessageEvent;
import com.yh.lq.event.message.LQGroupMessageEvent;
import com.yh.lq.event.message.LQPrivateMessageEvent;
import com.yh.lq.event.meta.LQHeartBeatMetaEvent;
import com.yh.lq.event.meta.LQLifecycleMetaEvent;
import com.yh.lq.event.notice.*;
import com.yh.lq.event.request.LQFriendRequestEvent;
import com.yh.lq.event.request.LQGroupRequestEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;


/**
 * 事件处理器
 * 先根据 post_type 分类，消息/通知/请求/元事件
 * 然后交给对应的继续分类
 * 职责链模式调用插件，返回MESSAGE_BLOCK停止
 */
@Slf4j
public class EventHandler {

    private ApplicationContext applicationContext;

    private LQPlugin defaultPlugin = new LQPlugin();

    public EventHandler(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void handle(LQ cq, JSONObject eventJson) {
        String postType = eventJson.getString("msgType");
        if(postType==null){
            return;
        }
        switch (postType) {
            case "msg": {
                handleMessage(cq, eventJson);
                break;
            }
//            case "notice": {
//                handleNotice(cq, eventJson);
//                break;
//            }
//            case "request": {
//                handleRequest(cq, eventJson);
//                break;
//            }
            case "meta": {
                handleMeta(cq, eventJson);
                break;
            }
        }
    }

    private void handleMessage(LQ cq, JSONObject eventJson) {
        String messageType = eventJson.getString("Event");
        switch (messageType) {
            case "1": {
                LQPrivateMessageEvent event = eventJson.toJavaObject(LQPrivateMessageEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onPrivateMessage(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "2": {
                LQGroupMessageEvent event = eventJson.toJavaObject(LQGroupMessageEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupMessage(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "3": {
                LQDiscussMessageEvent event = eventJson.toJavaObject(LQDiscussMessageEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onDiscussMessage(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
        }

    }

    private void handleNotice(LQ cq, JSONObject eventJson) {

        String noticeType = eventJson.getString("notice_type");

        switch (noticeType) {
            case "group_upload": {
                LQGroupUploadNoticeEvent event = eventJson.toJavaObject(LQGroupUploadNoticeEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupUploadNotice(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "group_admin": {
                LQGroupAdminNoticeEvent event = eventJson.toJavaObject(LQGroupAdminNoticeEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupAdminNotice(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "group_decrease": {
                LQGroupDecreaseNoticeEvent event = eventJson.toJavaObject(LQGroupDecreaseNoticeEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupDecreaseNotice(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "group_increase": {
                LQGroupIncreaseNoticeEvent event = eventJson.toJavaObject(LQGroupIncreaseNoticeEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupIncreaseNotice(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "group_ban": {
                LQGroupBanNoticeEvent event = eventJson.toJavaObject(LQGroupBanNoticeEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupBanNotice(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "friend_add": {
                LQFriendAddNoticeEvent event = eventJson.toJavaObject(LQFriendAddNoticeEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onFriendAddNotice(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
        }


    }

    private void handleRequest(LQ cq, JSONObject eventJson) {
        String requestType = eventJson.getString("request_type");
        switch (requestType) {
            case "friend": {
                LQFriendRequestEvent event = eventJson.toJavaObject(LQFriendRequestEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onFriendRequest(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "group": {
                LQGroupRequestEvent event = eventJson.toJavaObject(LQGroupRequestEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onGroupRequest(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
        }
    }

    private void handleMeta(LQ cq, JSONObject eventJson) {
        String metaType = eventJson.getString("metaEventType");
        switch (metaType) {
            case "connect": {
                LQHeartBeatMetaEvent event = eventJson.toJavaObject(LQHeartBeatMetaEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onHeartBeatMeta(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
            case "lifecycle": {
                LQLifecycleMetaEvent event = eventJson.toJavaObject(LQLifecycleMetaEvent.class);
                for (Class<? extends LQPlugin> pluginClass : cq.getPluginList()) {
                    if (getPlugin(pluginClass).onLifecycleMeta(cq, event) == LQPlugin.MESSAGE_BLOCK)
                        break;
                }
                break;
            }
        }
    }

    private LQPlugin getPlugin(Class<? extends LQPlugin> pluginClass) {
        try {
            return applicationContext.getBean(pluginClass);
        } catch (Exception e) {
            log.error("已跳过 {} ，请检查 @Component", pluginClass.getSimpleName());
            return defaultPlugin;
        }
    }
}
